package com.gui.connect;

import com.gui.exceptions.RedisConnectionException;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * Created by Gui on 2017/7/19.
 */
public class Connector implements Closeable {

    private String host;
    private int port;
    private Socket socket;

    protected Processor processor;
    protected Command command;

    public Connector(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void connect() {
        if (!this.isConnected()) {
            try {
                socket = new Socket();
                socket.setKeepAlive(true);
                socket.setTcpNoDelay(true);
                socket.setSoLinger(true, 0);
                socket.connect(new InetSocketAddress(host, port));

                processor = new Processor(socket.getInputStream());
                command = new Command(socket.getOutputStream());

            } catch (IOException e) {
                throw new RedisConnectionException(e);
            }
        }
    }

    public Command getCommand() {
        if (!this.isConnected()) {
            throw new RedisConnectionException("Redis is disconnected");
        }
        return command;
    }

    public Processor getProcessor() {
        if (!this.isConnected()) {
            throw new RedisConnectionException("Redis is disconnected");
        }
        return processor;
    }

    public void close() throws IOException {
        this.disconnect();
    }

    public void disconnect() {
        if (this.isConnected()) {
            try {
                processor.close();
                command.close();
                socket.close();
            } catch (IOException e) {
                throw new RedisConnectionException(e);
            }
        }
    }

    public boolean isConnected() {
        return socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected()
                && !socket.isInputShutdown() && !socket.isOutputShutdown();
    }
}
